package ru.dc.gui;

import ru.dc.object.UserInfo;

import java.util.*;

/**
 * <pre>
 * User: Penkov Vladimir
 * Date: 11.10.2010
 * Time: 16:45:49
 * </pre>
 */
public class UsersStore  {

    private List<UserInfo> users = new ArrayList<UserInfo>();
    private List<UserStoreListener> listenerList = new ArrayList<UserStoreListener>();
    /**
     * Содержит индекс элемента в списке users, по которому доступна информация о пользователе с указанным ником.
     */
    private Map<String, Integer> usersIndexes = new HashMap<String, Integer>();

    public int getSize() {
        return users.size();
    }

    public Object getElementAt(int index) {
        return users.get(index);
    }

    public void addUser(UserInfo userInfo) {
        if (!usersIndexes.containsKey(userInfo.getNick())) {
            users.add(userInfo);
            usersIndexes.put(userInfo.getNick(), users.size()-1);
            fireUserAdded(getSize()-1);
        }
        else {
            final Integer index = usersIndexes.get(userInfo.getNick());
            users.set(index, userInfo);
            fireUserUpdated(index);
        }

    }


    public boolean containsUser(String nick) {
        return usersIndexes.containsKey(nick);
    }

    public void addUsers(Collection<UserInfo> users) {
        for (UserInfo user : users) {
            addUser(user);
        }
    }

    public void removeUser(UserInfo userInfo) {
        if (usersIndexes.containsKey(userInfo.getNick())) {
            int index = usersIndexes.get(userInfo.getNick());
            users.remove(userInfo);
            usersIndexes.remove(userInfo.getNick());
            alignIndexes(index);
            fireUserRemoved(index);
        }
    }

    private void alignIndexes(int index) {
        for (String nick : usersIndexes.keySet()) {
            Integer i = usersIndexes.get(nick);
            if (i>index) {
                usersIndexes.put(nick, i-1);
            }
        }
    }

    public void removeUser(String nick) {
        if (usersIndexes.containsKey(nick)) {
            int index = usersIndexes.get(nick);
            users.remove(index);
            usersIndexes.remove(nick);
            alignIndexes(index);
            fireUserRemoved(index);
        }
    }




    public List<UserInfo> getUsers() {
        return Collections.unmodifiableList(users);
    }

    public UserInfo getUser(int index) {
        return users.get(index);
    }

    public int indexOf(UserInfo user) {
        return users.indexOf(user);
    }

    public void addEventListener(UserStoreListener l) {
        listenerList.add(l);
    }

    public void removeEventListener(UserStoreListener l) {
        listenerList.remove(l);
    }

    public void fireUserAdded(int index) {
        UserStoreEvent e = new UserStoreEvent();
        e.setIndex(index);
        e.setType(UserStoreEvent.USER_ADDED);
        fireStoreEvent(e);
    }

    public void fireUserUpdated(int index) {
        UserStoreEvent e = new UserStoreEvent();
        e.setIndex(index);
        e.setType(UserStoreEvent.USER_UPDATED);
        fireStoreEvent(e);
    }

    public void fireUserRemoved(int index) {
        UserStoreEvent e = new UserStoreEvent();
        e.setIndex(index);
        e.setType(UserStoreEvent.USER_REMOVED);
        fireStoreEvent(e);
    }


    public void fireStoreEvent(UserStoreEvent ev) {
        for (UserStoreListener l : listenerList) {
            l.onEvent(ev);
        }
    }

    public void clear() {
        users.clear();
        usersIndexes.clear();
        UserStoreEvent e = new UserStoreEvent();
        e.setIndex(-1);
        e.setType(UserStoreEvent.USER_REMOVED);
        fireStoreEvent(e);
    }
}
